<template>
  <div class="project-logic-container">
    <div class="project-logic-inner-wrap">
      <div class="logic-header">
        <p class="logic_title">
          {{ $t("form.logic.logicSettingsLabel") }}
        </p>
        <p class="text-desc">
          {{ $t("form.logic.logicDescription") }}
        </p>
        <el-row
          align="middle"
          justify="center"
          type="flex"
        >
          <el-col
            :offset="0"
            :span="8"
          >
            <el-text
              :type="isSave"
              size="default"
            >
              {{ saveMessage }}
            </el-text>
          </el-col>
          <el-col :span="5">
            <el-select
              v-model="logicTypeFilterVal"
              size="default"
              class="mr10"
              multiple
              clearable
              @change="handleLogicTypeFilterValChange"
            >
              <el-option
                v-for="item in logicTypeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-col>
          <el-col :span="8">
            <el-button
              class="ml10"
              icon="ele-Plus"
              size="default"
              :loading="isLoading"
              type="primary"
              @click="addLogicHandle"
            >
              <span class="label">{{ $t("form.logic.addLogicLabel") }}</span>
            </el-button>
            <el-popconfirm
              :title="$t('form.logic.cleanAll')"
              @confirm="() => (logicList = [])"
            >
              <template #reference>
                <el-button size="default">
                  <el-icon :size="16">
                    <ele-Delete />
                  </el-icon>
                  {{ $t("form.logic.cleanLogic") }}
                </el-button>
              </template>
            </el-popconfirm>
          </el-col>
        </el-row>
        <el-divider />
      </div>
      <div
        class="logic-item-container"
        v-loading="loading"
      >
        <el-empty v-if="isDataEmpty" />
        <div
          class="logic-scrollbar-wrap"
          v-if="allProjectItemList.length"
        >
          <div
            v-for="(logicItem, index) in logicList"
            :key="logicItem.id"
            class="logic-item"
            v-show="logicTypeFilterVal.length === 0 || logicTypeFilterVal.includes(logicItem.triggerList[0]?.type)"
          >
            <el-card
              class="logic-card"
              shadow="never"
            >
              <div class="logic-item-delbtn">
                <el-popconfirm
                  :title="$t('form.logic.confirmDeleteLabel')"
                  @confirm="handleRemoveLogicItem(index)"
                >
                  <template #reference>
                    <el-button
                      link
                      type="danger"
                    >
                      <el-icon :size="16">
                        <ele-Delete />
                      </el-icon>
                    </el-button>
                  </template>
                </el-popconfirm>
              </div>
              <el-row
                v-for="(cItem, cIndex) in logicItem.conditionList"
                :key="cItem"
                :gutter="10"
                align="middle"
                class="mt5"
                justify="center"
                type="flex"
              >
                <el-col
                  :span="3"
                  class="text-center"
                >
                  <span
                    class="text-left"
                    v-if="cIndex === 0"
                  >
                    {{ $t("form.logic.ifFormComponentLabel") }}
                  </span>
                  <el-select
                    v-else
                    v-model="cItem.relation"
                    :disabled="cIndex !== 1"
                    @change="(val: string) => relationChangeHandle(val, logicItem)"
                    size="small"
                  >
                    <el-option
                      :label="$t('form.logic.andLabel')"
                      value="AND"
                    />
                    <el-option
                      :label="$t('form.logic.orLabel')"
                      value="OR"
                    />
                  </el-select>
                </el-col>
                <el-col :span="7">
                  <select-wrap
                    :placeholder="$t('form.logic.select')"
                    :text="componentMap.get(cItem.formItemId || '')"
                    @click="event => handleConditionItemClick(event, cItem)"
                  />
                </el-col>
                <el-col :span="5">
                  <select-wrap
                    :text="expressionMap[cItem.expression || '']"
                    :placeholder="$t('form.logic.condition')"
                    @click="event => handleExpressionClick(event, cItem)"
                  />
                </el-col>
                <el-col :span="6">
                  <!--  下拉问题使用选项-->
                  <FormOptionSelect
                    class="width100"
                    size="default"
                    valueProp="value"
                    :placeholder="$t('form.logic.option')"
                    v-if="['RADIO', 'CHECKBOX', 'SELECT', 'IMAGE_SELECT'].includes(getFormItemIdType(cItem.formItemId))"
                    v-model="cItem.optionValue"
                    allow-create
                    clearable
                    default-first-option
                    filterable
                    :item="getFormItemOptions(cItem.formItemId)"
                  ></FormOptionSelect>
                  <!--  评分使用数字框-->
                  <el-input-number
                    v-else-if="getFormItemIdType(cItem.formItemId) === 'RATE'"
                    v-model="cItem.optionValue"
                    :min="0"
                  />
                  <el-input
                    v-else
                    :disabled="cItem.expression && ['notNull', 'isNull'].includes(cItem.expression)"
                    v-model="cItem.optionValue"
                    size="default"
                  ></el-input>
                </el-col>
                <el-col :span="3">
                  <el-button
                    link
                    type="primary"
                    @click="addConditionHandle(logicItem, cItem)"
                  >
                    <el-icon size="18">
                      <ele-CirclePlus />
                    </el-icon>
                  </el-button>
                  <el-button
                    v-if="cIndex !== 0"
                    class="remove"
                    link
                    type="primary"
                    @click="removeConditionHandle(logicItem, index, cIndex)"
                  >
                    <el-icon size="18">
                      <ele-Remove />
                    </el-icon>
                  </el-button>
                </el-col>
              </el-row>
              <el-row
                v-for="(trigger, tindex) in logicItem.triggerList"
                :key="trigger"
                align="middle"
                type="flex"
                class="mt5"
              >
                <el-col :span="3"></el-col>
                <el-col
                  :span="6"
                  class="text-center"
                >
                  <span class="result-text">{{ $t("form.logic.thenLabel") }}</span>
                  <select-wrap
                    class="ml10"
                    style="width: 80%"
                    :placeholder="$t('form.logic.type')"
                    :text="logicTypeMap[trigger.type || '']"
                    @click="event => handleTriggerTypeClick(event, trigger)"
                  />
                </el-col>
                <el-col :span="10">
                  <select-wrap
                    v-if="!['finish', 'showOption', 'checkOption'].includes(trigger.type)"
                    class="ml10"
                    style="width: 50%"
                    :placeholder="$t('form.logic.question')"
                    :text="componentMap.get(trigger.formItemId || '')"
                    @click="event => handleTriggerItem(event, logicItem, trigger)"
                  />
                  <span
                    v-if="trigger.type === 'show'"
                    class="result-text"
                  >
                    {{ $t("form.logic.otherwiseNotDisplayLabel") }}
                  </span>
                  <span
                    v-if="trigger.type === 'jump'"
                    class="result-text"
                  >
                    {{ $t("form.logic.otherwiseShowNextLabel") }}
                  </span>
                  <el-cascader
                    class="ml10"
                    style="width: 50%"
                    v-if="['showOption', 'checkOption'].includes(trigger.type)"
                    v-model="trigger.optionValue"
                    :placeholder="$t('form.logic.question')"
                    size="default"
                    :props="{ multiple: true }"
                    collapse-tags
                    clearable
                    :options="getFormOptionItems"
                  ></el-cascader>
                </el-col>
                <el-col :span="4">
                  <el-button
                    link
                    type="primary"
                    @click="addTriggerItemHandle(logicItem)"
                  >
                    <el-icon size="18">
                      <ele-CirclePlus />
                    </el-icon>
                  </el-button>
                  <el-button
                    v-if="tindex !== 0"
                    class="remove"
                    link
                    type="primary"
                    @click="removeTriggerItemHandle(logicItem, index, tindex)"
                  >
                    <el-icon size="18">
                      <ele-Remove />
                    </el-icon>
                  </el-button>
                </el-col>
              </el-row>
            </el-card>
          </div>
        </div>
      </div>
    </div>
    <select-popover
      ref="conditionSelectPopoverRef"
      :options="conditionProjectItemList"
      v-if="conditionProjectItemList.length"
      :option-props="{
        value: 'formItemId',
        label: 'textLabel'
      }"
      filterable
      @change="handleSelectPopover"
    />
    <select-popover
      ref="targetItemPopoverRef"
      :options="allProjectItemList"
      v-if="allProjectItemList.length"
      :option-props="{
        value: 'formItemId',
        label: 'textLabel'
      }"
      filterable
      @change="handleSelectPopover"
    />
    <select-popover
      ref="logicTypePopoverRef"
      :options="logicTypeOptions"
      v-if="logicTypeOptions.length"
      @change="handleSelectPopover"
    />
    <select-popover
      ref="expressionPopoverRef"
      :options="expressionOptions"
      v-if="expressionOptions.length"
      @change="handleSelectPopover"
    />
  </div>
</template>

<script name="ProjectLogic" setup lang="ts">
import { computed, nextTick, onActivated, onMounted, reactive, ref, watch } from "vue";
import { jsonSimpleClone, removeHtmlTag } from "@/views/formgen/utils";
import { getFormLogicRequest, listProjectItemRequest, saveFormLogicRequest, UserFormItemEntity } from "@/api/project/form";
import { i18n } from "@/i18n";
import FormOptionSelect from "@/views/components/FormOptionSelect/index.vue";
import { useRoute } from "vue-router";
import { debounce } from "lodash-es";
import { Condition, LogicItem, Trigger } from "@/views/form/logic/types";
import SelectPopover from "./SelectPopover.vue";
import SelectWrap from "./SelectWrap.vue";
import { MessageUtil } from "@/utils/messageUtil";
import { formDesign } from "@/views/formgen/components/FormDesign/hooks/useFormDesign";
import { formItemConvertData } from "@/views/formgen/utils/convert";
const saveMessage = ref("");
const isSave = ref("info");
const isLoading = ref(false);
const formKey = ref<string>("");

const logicTypeFilterVal = ref<string[]>([]);

const isDataEmpty = ref<boolean>(false);

const conditionSelectPopoverRef = ref<InstanceType<typeof SelectPopover> | null>(null);
const logicTypePopoverRef = ref<InstanceType<typeof SelectPopover> | null>(null);
const expressionPopoverRef = ref<InstanceType<typeof SelectPopover> | null>(null);
const targetItemPopoverRef = ref<InstanceType<typeof SelectPopover> | null>(null);

// 过滤列表
const handleLogicTypeFilterValChange = (val: string[]) => {
  if (!val.length) {
    isDataEmpty.value = logicList.value.length === 0;
    return;
  }
  // 判断是否过滤到数据
  const index = logicList.value.findIndex(item => {
    console.log(val);
    console.log(item);
    return val.includes(item.triggerList[0].type);
  });
  isDataEmpty.value = index === -1;
};

// 默认逻辑项
const defaultLogicItem = reactive({
  triggerList: [
    {
      formItemId: null,
      type: "show"
    }
  ],
  conditionList: [
    {
      formItemId: null,
      expression: null,
      optionValue: null,
      relation: "AND"
    }
  ]
});

// 逻辑类型表达式
const logicTypeOptions = ref([
  {
    value: "show",
    label: i18n.global.t("form.logic.showLabel")
  },
  {
    value: "jump",
    label: i18n.global.t("form.logic.jumpLabel")
  },
  {
    value: "finish",
    label: i18n.global.t("form.logic.finishLabel")
  },
  {
    value: "showOption",
    label: i18n.global.t("form.logic.showOptionLabel")
  },
  {
    value: "checkOption",
    label: i18n.global.t("form.logic.checkOption")
  }
]);

const logicTypeMap: any = ref(
  logicTypeOptions.value.reduce((acc: any, curr: any) => {
    acc[curr.value] = curr.label;
    return acc;
  }, {})
);

const expressionOptions = ref([
  {
    value: "eq",
    label: i18n.global.t("form.logic.eq"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "RATE", "INPUT", "NPS", "NUMBER"]
  },
  {
    value: "ne",
    label: i18n.global.t("form.logic.ne"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "RATE", "INPUT", "NPS", "NUMBER"]
  },
  {
    value: "gt",
    label: i18n.global.t("form.logic.gt"),
    types: ["RATE", "NPS", "NUMBER"]
  },
  {
    value: "ge",
    label: i18n.global.t("form.logic.ge"),
    types: ["RATE", "NPS", "NUMBER"]
  },
  {
    value: "lt",
    label: i18n.global.t("form.logic.lt"),
    types: ["RATE", "NPS", "NUMBER"]
  },
  {
    value: "le",
    label: i18n.global.t("form.logic.le"),
    types: ["RATE", "NPS", "NUMBER"]
  },
  {
    value: "isNull",
    label: i18n.global.t("form.logic.null"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "RATE", "INPUT", "NPS", "NUMBER"]
  },
  {
    value: "notNull",
    label: i18n.global.t("form.logic.notnull"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "RATE", "INPUT", "NPS", "NUMBER"]
  },
  {
    value: "like",
    label: i18n.global.t("form.logic.like"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "INPUT"]
  },
  {
    value: "notLike",
    label: i18n.global.t("form.logic.notlike"),
    types: ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "INPUT"]
  }
]);

const expressionMap: any = ref(
  expressionOptions.value.reduce((acc: any, curr: any) => {
    acc[curr.value] = curr.label;
    return acc;
  }, {})
);

const componentMap = new Map<string, string>();

const allProjectItemList = ref<UserFormItemEntity[]>([]);
const logicList = ref<LogicItem[]>([]);

const route = useRoute();

const loading = ref(true);

interface ChangeSelect {
  type: "condition" | "trigger" | "expression";
  obj: any;
}

const handleSelectPopover = () => {
  if (changeSelectObj.value) {
    switch (changeSelectObj.value.type) {
      case "condition":
        changeSelectObj.value.obj["optionValue"] = null;
        break;
      case "trigger":
        const type = changeSelectObj.value.obj["type"];
        if (["finish", "showOption", "checkOption"].includes(type)) {
          changeSelectObj.value.obj["formItemId"] = null;
        }
        break;
    }
  }
};

const changeSelectObj = ref<ChangeSelect | null>(null);

onMounted(async () => {
  loading.value = true;
  formKey.value = route.query.key as string;
  queryProjectLogic();
});

onActivated(async () => {
  await queryProjectItems();
});

const loadEnd = ref(false);

watch(
  logicList,
  val => {
    console.log(val);
    if (val && loadEnd.value) {
      saveProjectLogic(val);
      isSave.value = "info";
      saveMessage.value = i18n.global.t("form.logic.handling");
    }
  },
  { deep: true }
);

const addConditionHandle = (logicItem: LogicItem, cItem: Condition) => {
  logicItem.conditionList.push({
    expression: null,
    formItemId: null,
    optionValue: null,
    relation: cItem.relation
  });
};

const removeConditionHandle = (logicItem: LogicItem, logicIndex: number, index: number) => {
  logicItem.conditionList.splice(index, 1);
};

const addTriggerItemHandle = (logicItem: LogicItem) => {
  logicItem.triggerList.push({ type: "show" });
};

const removeTriggerItemHandle = (logicItem: LogicItem, logicIndex: number, index: number) => {
  logicItem.triggerList.splice(index, 1);
};

const addLogicHandle = () => {
  isLoading.value = true;
  const newLogicItem = jsonSimpleClone(defaultLogicItem);
  newLogicItem.id = new Date().getTime();
  logicList.value.push(newLogicItem);
  isDataEmpty.value = false;
};

const handleConditionItemClick = (event: any, cItem: Condition) => {
  changeSelectObj.value = {
    type: "condition",
    obj: cItem
  };
  conditionSelectPopoverRef.value.handleClick(event, cItem, "formItemId");
};

const handleExpressionClick = (event: any, cItem: Condition) => {
  if (!cItem.formItemId) {
    MessageUtil.warning(i18n.global.t("form.logic.question"));
    return;
  }
  changeSelectObj.value = null;
  let type = cItem.formItemId.replace(/\d+/, "").toUpperCase();
  let notShowKey: string[] = [];
  // 不同类型只有不同的条件类型
  expressionOptions.value.forEach((item: any) => {
    if (!item.types.includes(type)) {
      notShowKey.push(item.value);
    }
  });
  expressionPopoverRef.value.handleClick(event, cItem, "expression", notShowKey);
};

const relationChangeHandle = (val: string, logicItem: LogicItem) => {
  logicItem.conditionList.forEach((item: Condition) => {
    //@ts-ignore
    item!.relation = val;
  });
};

// 支持逻辑的组件
const supportLogicComponentList = ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT", "RATE", "INPUT", "NPS", "NUMBER"];

const conditionProjectItemList = ref([]);

const handleTriggerItem = (event: any, logicItem: LogicItem, target: Trigger) => {
  let selectedFormItemList = logicItem.conditionList.map((item: Condition) => item.formItemId) || [];
  targetItemPopoverRef.value.handleClick(event, target, "formItemId", selectedFormItemList);
};

const getFormItemOptions = (formItemId: string | null) => {
  let formItem = allProjectItemList.value.find(item => item.formItemId == formItemId);
  if (formItem) {
    return {
      field: formItem
    };
  }
};

const handleRemoveLogicItem = (index: number) => {
  logicList.value.splice(index, 1);
};

const getFormItemIdType = (formItemId: string | null) => {
  if (!formItemId) return "";
  return formItemId.replace(/\d+/, "").toUpperCase();
};

const queryProjectLogic = () => {
  getFormLogicRequest({ formKey: formKey.value }).then(res => {
    if (res.data) {
      logicList.value = res.data.scheme ? res.data.scheme : [];
    }
    if (!res.data || !logicList.value || !logicList.value.length) {
      isDataEmpty.value = true;
    }
    loading.value = false;
    nextTick(() => {
      loadEnd.value = true;
    });
  });
};

const handleTriggerTypeClick = (event: any, trigger: Trigger) => {
  changeSelectObj.value = {
    type: "trigger",
    obj: trigger
  };
  logicTypePopoverRef.value.handleClick(event, trigger, "type");
};

const { drawingList } = formDesign;

const queryProjectItems = async () => {
  let list = drawingList.value.map(item => {
    let data: any = formItemConvertData(item, formKey.value);
    data!.textLabel = removeHtmlTag(data.label);
    return data;
  }) as UserFormItemEntity[];
  console.log(list);
  if (!list || !list.length) {
    const res = await listProjectItemRequest({ key: formKey.value });
    list = res.data;
  }
  if (list) {
    allProjectItemList.value = list.filter((item: UserFormItemEntity) => {
      return item.type !== "PAGINATION";
    });
    console.log(allProjectItemList);
    conditionProjectItemList.value = jsonSimpleClone(allProjectItemList.value).filter((item: UserFormItemEntity) => {
      return supportLogicComponentList.includes(item.type);
    });
    //生成映射
    allProjectItemList.value.forEach((item: UserFormItemEntity) => {
      componentMap.set(item.formItemId as string, item.textLabel);
    });
  }
};

const saveProjectLogic = debounce(function (logicList: LogicItem[]) {
  let data = { formKey: formKey.value, scheme: logicList };
  saveFormLogicRequest(data).then(() => {
    isLoading.value = false;
    isSave.value = "";
    saveMessage.value = i18n.global.t("form.logic.isSave");
  });
}, 430);

// 获取所有选项的题目
const getFormOptionItems = computed(() => {
  console.log(allProjectItemList);
  return allProjectItemList.value
    .filter((item: UserFormItemEntity) => {
      return ["RADIO", "CHECKBOX", "SELECT", "IMAGE_SELECT"].includes(item.type);
    })
    .map((item: UserFormItemEntity) => {
      const options = item.scheme?.config?.options;
      return {
        value: item.formItemId,
        label: item.textLabel,
        children: options?.map((option: any) => {
          return {
            value: option.value,
            label: option.label ? removeHtmlTag(option.label) : ""
          };
        })
      };
    });
});
</script>

<style lang="scss" scoped>
.project-logic-container {
  width: 100%;
  height: calc(100vh - 85px);
  padding: 0;
  justify-content: center;
  position: relative;
  overflow: hidden;
  background-color: #fff;
  user-select: none;

  .project-logic-inner-wrap {
    border-radius: 8px;
    padding: 5px;
    width: 980px;
    min-width: 980px;
    height: 100%;
    margin: 0 auto;
  }

  .logic_title {
    font-size: 18px;
    height: 45px;
    line-height: 45px;
    color: #484848;
    text-align: left;
    margin-top: 20px;
  }
}

.text-desc {
  font-size: 14px;
  line-height: 20px;
  color: #9b9b9b;
  margin-bottom: 10px;
}

.not-logic-container {
  .el-icon-circle-plus-outline {
    font-size: 20px;
  }

  .label {
    font-size: 18px;
  }
}

.logic-item-container {
  height: calc(100% - 200px);

  .logic-scrollbar-wrap {
    height: 100%;
    overflow-y: auto;
  }

  .tips {
    font-size: 14px;
    color: #aaa;
  }

  .label {
    font-size: 15px;
  }

  .remove {
    color: #ff4949;
  }
}

.el-icon-circle-plus-outline,
.el-icon-remove-outline {
  font-size: 24px;
}

.logic-item {
  position: relative;

  .logic-item-delbtn {
    display: flex;
    justify-content: flex-end;
  }
}

.logic-card {
  border-radius: 10px;
  background-color: var(--el-color-primary-light-10);
  margin-top: 10px;
}
.result-text {
  line-height: 32px;
  margin-left: 20px;
  vertical-align: top;
}
</style>
